﻿using System;
using System.Globalization;
using System.IO;
using System.Reflection;
//using System.Threading;
using System.Windows;
using System.Windows.Markup;
using System.Windows.Shell;
using GalaSoft.MvvmLight.Messaging;
using RSSFeedReader.Data.Models;
using RSSFeedReader.Resources;
using RSSFeedReader.Services;
using RSSFeedReader.ViewModels;
using RSSFeedReader.ViewModels.Messages;
using RSSFeedReader.Views;
using SingleInstanceApplication;

namespace RSSFeedReader
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class RSSFeedReaderApplication : ILoggerService
    {
        #region Members

        /// <summary>
        /// Constant string for add new feed.
        /// </summary>
        public const string AddNewFeedCommand = "AddNewFeed";

        #endregion

        #region Override Methods

        /// <summary>
        /// Override OnStartUp to set the culture info.
        /// </summary>
        /// <param name="e"></param>
        protected override void OnStartup(StartupEventArgs e)
        {
            // register single instance app. and check for existence of other process
            if (!ApplicationInstanceManager.CreateSingleInstance(
                    Assembly.GetExecutingAssembly().GetName().Name,
                    SingleInstanceCallback)) return; // exit, if same app. is running

            // *******************************************************************
            // Uncomment one of the lines of code that create a CultureInfo
            // in order to see the application run with localized text in the UI.
            // *******************************************************************

            //CultureInfo culture = null;

            // ITALIAN
            //culture = new CultureInfo("it-IT");


            // FRENCH
            //culture = new CultureInfo("fr-CH");


            // GERMAN
            //culture = new CultureInfo("de-DE");

            //if (culture != null)
            //{
            //    Thread.CurrentThread.CurrentCulture = culture;
            //    Thread.CurrentThread.CurrentUICulture = culture;
            //}

            // Ensure the current culture passed into bindings is the OS culture.
            // By default, WPF uses en-US as the culture, regardless of the system settings.
            FrameworkElement.LanguageProperty.OverrideMetadata(
              typeof(FrameworkElement),
              new FrameworkPropertyMetadata(
                  XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag)));

            // If being loaded from firefox for example to subscribe to a feed.
            RegisterMessages();
            SetupJumpList();
            ProcessCommandLineArgs(e.Args);
            base.OnStartup(e);
        }

        /// <summary>
        /// Event handler for when the RSSFeedReaderApplication is shutting down.
        /// </summary>
        /// <param name="e">Event arguments describing the event.</param>
        protected override void OnExit(ExitEventArgs e)
        {
            ChannelDataSource.Instance.Save();
            base.OnExit(e);
        }

        #endregion

        #region Private Methods

        private void RegisterMessages()
        {
            Messenger.Default.Register<ShowWindowMessage<AddNewFeedViewModel>>(this, OnShowAddNewFeedView);
            Messenger.Default.Register<ShowWindowMessage<ManageFeedsViewModel>>(this, OnShowManageFeedsView);
            Messenger.Default.Register<ShowWindowMessage<AddNewFolderViewModel>>(this, OnShowAddNewFolderView);
            Messenger.Default.Register<ShowWindowMessage<RenameChannelViewModel>>(this, OnShowRenameChannelView);
            Messenger.Default.Register<ShowWindowMessage<MoveToFolderViewModel>>(this, OnShowMoveToFolderView);
            Messenger.Default.Register<ShowWindowMessage<ChannelPropertiesViewModel>>(this, OnShowChannelPropertiesView);
        }

        private void OnShowChannelPropertiesView(ShowWindowMessage<ChannelPropertiesViewModel> e)
        {
            var channelPropertiesView = new ChannelPropertiesView { Owner = MainWindow, DataContext = e.ViewModel };
            channelPropertiesView.ShowDialog();
        }

        private void OnShowMoveToFolderView(ShowWindowMessage<MoveToFolderViewModel> e)
        {
            var moveToFolderView = new MoveToFolderView { Owner = MainWindow, DataContext = e.ViewModel };
            moveToFolderView.ShowDialog();
        }

        private void OnShowRenameChannelView(ShowWindowMessage<RenameChannelViewModel> e)
        {
            var renameChannelView = new RenameChannelView { Owner = MainWindow, DataContext = e.ViewModel };
            renameChannelView.ShowDialog();
        }

        private void OnShowAddNewFolderView(ShowWindowMessage<AddNewFolderViewModel> e)
        {
            var addNewFolderView = new AddNewFolderView { Owner = MainWindow, DataContext = e.ViewModel };
            addNewFolderView.ShowDialog();
        }

        private void OnShowManageFeedsView(ShowWindowMessage<ManageFeedsViewModel> e)
        {
            var manageFeedsView = new ManageFeedsView { Owner = MainWindow, DataContext = e.ViewModel };
            manageFeedsView.ShowDialog();
        }

        private void OnShowAddNewFeedView(ShowWindowMessage<AddNewFeedViewModel> e)
        {
            var addNewFeedView = new AddNewFeedView { Owner = MainWindow, DataContext = e.ViewModel };
            addNewFeedView.ShowDialog();
        }

        /// <summary>
        /// Set up the JumpList for Windows 7
        /// </summary>
        private static void SetupJumpList()
        {
            var addNewFeed = new JumpTask
                             {
                                 ApplicationPath = Assembly.GetExecutingAssembly().Location, 
                                 IconResourcePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Resources\\Images\\add.ico"), 
                                 Arguments = AddNewFeedCommand, 
                                 Title = Strings.AddNewFeed, 
                                 Description = Strings.AddNewFeed
                             };
            var jumpList = new JumpList();
            jumpList.JumpItems.Add(addNewFeed);
            JumpList.SetJumpList(Current, jumpList);
        }

        private static void ProcessCommandLineArgs(string[] args)
        {
            if (args.Length < 1) return;

            foreach (string arg in args)
            {
                if (arg.Equals(AddNewFeedCommand))
                {
                    Messenger.Default.Send(new ShowWindowMessage<AddNewFeedViewModel>(new AddNewFeedViewModel()));
                }
                else if (arg.Contains("feed:"))
                {
                    string feed = arg.Replace("feed:", "http:");

                    if (!ChannelDataSource.Instance.ContainsChannel(feed))
                        ChannelDataSource.Instance.AddChannel(feed);
                }
            }
        }

        /// <summary>
        /// Single instance callback handler.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="args">The <see cref="SingleInstanceApplication.InstanceCallbackEventArgs"/> instance containing the event data.</param>
        private void SingleInstanceCallback(object sender, InstanceCallbackEventArgs args)
        {
            if (args == null || Dispatcher == null) return;
            Action<bool> d = x =>
            {
                SetupJumpList();
                ProcessCommandLineArgs(args.CommandLineArgs);
            };
            Dispatcher.Invoke(d, true);
        }

        #endregion

        #region ILoggerService Members

        /// <summary>
        /// Logs to the event log using the params provided.
        /// </summary>
        /// <param name="type">The type of logging.</param>
        /// <param name="message">The actual message string to be logged.</param>
        public void LogMessage(string type, string message)
        {
            string dateTime = DateTime.Now.ToString();
            message = string.Format("{0}\t{1}\t{2}", dateTime, type, message);

            using (TextWriter tx = File.AppendText(MainViewModel.LogFile))
            {
                tx.WriteLine(message);
            }
        }

        #endregion
    }
}
